/*+***********************************************************************************
 Filename: 03_tinycore_step01\src\top.v
 Description: demo the construction of a simple tiny-core.
              step01: fetch instruction.

 Modification:
   2022.10.12 Creation   H.Zheng

Copyright (C) 2022  Zheng Hui (hzheng@gzhu.edu.cn)

License: MulanPSL-2.0

***********************************************************************************-*/

module top
(
    input wire [1:0] button,
    input wire sys_clk,
    output wire [5:0] led
);
    //PLL
    wire clk_200MHz;
    Gowin_rPLL m_pll(
        .clkout(clk_200MHz), //output clkout
        .clkin(sys_clk) //input clkin
    );

    //
    wire reset_n = button[1];

    //core clk
    reg [24:0] counter;

    always @(posedge sys_clk or negedge reset_n) begin
        if (~reset_n) begin
            counter <= 0;
        end
        else begin
            counter <= counter + 1'b1;
        end
    end

//code style 1: hierarchical(modular) style

    //core
    wire core_clk = counter[24];
    wire [31:0] ibus_addr;
    wire ibus_re;
    wire [31:0] instruction;
    wire [31:0] monitor_port;

    core m_core (
        .core_clk(core_clk),
        .reset_n(reset_n),
        .ibus_addr(ibus_addr),
        .ibus_re(ibus_re),
        .instruction(instruction),
        .monitor_port(monitor_port)
    );

    //IROM
    //address and control input from core
    //data output to core

    Gowin_pROM I_ROM(
        .dout(instruction), //output [31:0] dout
        .clk(clk_200MHz), //input clk
        .oce(ibus_re), //input oce
        .ce(1'b1), //input ce
        .reset(~reset_n), //input reset
        .ad(ibus_addr[2:0]) //input [2:0] ad
    );

    //display
    assign led = ~monitor_port[5:0];


//code style 2: direct
/*
    //PC
    reg [31:0] program_counter;

    always @(posedge core_clk or negedge reset_n) begin
        if (~reset_n) begin
            program_counter <= 0;
        end
        else begin
            program_counter <= program_counter + 1'b1;
        end
    end

    //ROM
    wire [31:0] instruction;
    Gowin_pROM I_ROM(
        .dout(instruction), //output [31:0] dout
        .clk(clk_200MHz), //input clk
        .oce(1'b1), //input oce
        .ce(1'b1), //input ce
        .reset(~reset_n), //input reset
        .ad(program_counter[2:0]) //input [2:0] ad
    );

    //display
    assign led = ~instruction[5:0];
*/

endmodule